const express = require('express');
const { createServer } = require('http');
const { io } = require('socket.io-client');
const debug = require('debug')('tunnel:proxy');

const app = express();

// 添加 body-parser 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const httpServer = createServer(app);

// 从环境变量获取隧道服务器地址
const TUNNEL_SERVER = process.env.TUNNEL_SERVER || 'http://localhost:23909';
const socket = io(TUNNEL_SERVER);

// 存储等待响应的请求
const pendingRequests = new Map();

// Socket.IO 连接处理
socket.on('connect', () => {
  debug('已连接到隧道服务器');
});

socket.on('disconnect', () => {
  debug('与隧道服务器断开连接');
});

// 处理隧道服务器的响应
socket.on('proxyResponse', (data) => {
  const { requestId, response } = data;
  debug('收到响应:', requestId);

  const pendingReq = pendingRequests.get(requestId);
  if (pendingReq) {
    const { res } = pendingReq;
    
    // 设置响应头
    if (response.headers) {
      Object.entries(response.headers).forEach(([key, value]) => {
        if (!['connection', 'transfer-encoding'].includes(key.toLowerCase())) {
          res.set(key, value);
        }
      });
    }

    // 发送响应
    res.status(response.status).send(response.body);
    pendingRequests.delete(requestId);
  }
});

// HTTP 请求处理
app.use(async (req, res) => {
  const requestId = Math.random().toString(36).substr(2, 9);
  
  // 从子域名或查询参数中获取隧道ID
  let tunnelId = req.query.tunnel;
  if (!tunnelId) {
    const host = req.headers.host;
    if (host) {  // 添加 host 存在性检查
      const match = host.match(/^([^.]+)\./);
      if (match) {
        tunnelId = match[1];
      }
    }
  }

  if (!tunnelId) {
    debug('未找到隧道ID');
    return res.status(400).send('Missing tunnel ID');
  }

  const requestData = {
    id: requestId,
    method: req.method,
    path: req.path,
    headers: req.headers,
    body: req.body,
    query: req.query
  };

  debug('处理请求:', requestId, req.method, req.path, '隧道ID:', tunnelId);

  // 存储请求上下文
  pendingRequests.set(requestId, { req, res });

  // 设置请求超时
  const timeoutId = setTimeout(() => {
    if (pendingRequests.has(requestId)) {
      debug('请求超时:', requestId);
      res.status(504).send('Gateway Timeout');
      pendingRequests.delete(requestId);
    }
  }, 30000);

  // 发送请求到隧道服务器
  socket.emit('proxyRequest', {
    requestId,
    tunnelId,
    request: requestData
  });
});

// 错误处理
app.use((err, req, res, next) => {
  debug('代理错误:', err);
  res.status(500).send('Proxy Error');
});

// 从环境变量获取代理服务器端口
const PORT = process.env.PORT || 23908;
httpServer.listen(PORT, () => {
  debug(`代理服务器运行在端口 ${PORT}`);
});

// 优雅退出
process.on('SIGINT', () => {
  debug('正在关闭代理服务器...');
  socket.close();
  httpServer.close(() => {
    process.exit(0);
  });
});
